package com.tbl.modules.agv.service.webapi.server;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.google.common.collect.Maps;
import com.tbl.modules.agv.entity.agvtask.AgvTask;
import com.tbl.modules.agv.entity.agvtask.AgvTaskLog;
import com.tbl.modules.agv.service.agvtask.AgvTaskLogService;
import com.tbl.modules.agv.service.agvtask.AgvTaskService;
import com.tbl.modules.agv.service.webapi.client.WebApiClientService;
import com.tbl.modules.agv.util.RequestUtils;
import com.tbl.modules.platform.controller.AbstractController;
import com.tbl.modules.wms.constant.EmumConstant;
import com.tbl.modules.wms.dao.baseinfo.ShelfDAO;
import com.tbl.modules.wms.entity.baseinfo.Shelf;
import com.tbl.modules.wms.service.baseinfo.ShelfService;
import com.tbl.modules.wms.service.interfacelog.InterfaceLogService;
import com.tbl.modules.wms2.entity.baseinfo.YclInventory;
import com.tbl.modules.wms2.entity.report.YclInventoryEntity;
import com.tbl.modules.wms2.service.baseinfo.YclInventoryService;
import com.tbl.modules.wms2.service.report.InventoryService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.Map;

/**
 * AGV webapi接口服务端
 * @author 70486
 */
@RestController
@RequestMapping(value = "/agv")
public class WebApiServer extends AbstractController {

    /**
     * 日志信息
     */
    private final Logger logger = LoggerFactory.getLogger(getClass());
    /**
     * 接口日志
     */
    private InterfaceLogService interfaceLogService;
    /**
     * http接口客户端
     */
    private WebApiClientService webApiClientService;
    /**
     * agv任务主表
     */
    @Autowired
    private AgvTaskService agvTaskService;
    /**
     * 库料库存
     */
    @Autowired
    private InventoryService inventoryService;
    /**
     * agv日志表
     */
    @Autowired
    private AgvTaskLogService agvTaskLogService;
    /**
     * 库位
     */
    @Autowired
    private ShelfService shelfService;

    /**
     * AGV执行情况,执行情况共有7种情况；1=开始、3=开始取货、4=取货完成、5=开始卸货、6=卸货完成、2=完成、7=取消
     * @param request HttpServletRequest
     * @return String {"success":""，"errCode":"","errMsg":""}
     */
    @PostMapping(value = "/taskStatus")
    @ResponseBody
    public String taskStatus(HttpServletRequest request) {
        String jsonStr = "";
        Map<String, Object> returnMap = Maps.newHashMap();
        try {
            jsonStr = RequestUtils.getPostData(request);
            logger.info("AGV执行情况接收报文："+jsonStr);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Map<String,Object> jsonMap = JSON.parseObject(jsonStr);
        //wms生成的任务号
        String taskNo = (String) jsonMap.get("taskNo");
        //执行情况共有6种情况；1=开始、3=开始取货、4=取货完成、5=开始卸货、6=卸货完成、2=完成、7=取消
        int state = (Integer) jsonMap.get("state");

        switch (state){
            //1=开始
            case 1 : break;
            //3=开始取货
            case 3 : break;
            //4=取货完成
            case 4 : break;
            //5=开始卸货
            case 5 : break;
            //6=卸货完成
            case 6 : break;
            //2=完成
            case 2 :
                AgvTask agvTask = agvTaskService.selectOne(new EntityWrapper<AgvTask>().eq("TASK_NO", taskNo));
                switch (agvTask.getBussinessType()){
                    //移库调拨
                    case 4 :
                        //调拨减掉库存
                        updateCutInventory(agvTask);
                        break;
                    //叫料
                    case 1 :
                        //叫料完成库存表需要减去相应的库存
                        updateCutInventory(agvTask);
                        break;
                    //入库（退料）
                    case 2 :
                        //退料完成需要插入相应库存
                        updateAddInventory(agvTask);
                        break;
                    default:break;
                }
                break;
            //7=取消
            case 7 : break;
            default:break;
        }
        //AGV日志表记录
        AgvTaskLog agvlog = new AgvTaskLog();
        agvlog.setAgvState(state);
        agvlog.setAgvTime(DateUtil.date());
        agvlog.setTaskNo(taskNo);
        agvTaskLogService.insert(agvlog);

        returnMap.put("success", "True");
        returnMap.put("errCode", "");
        returnMap.put("errMsg", "");
        return JSONObject.toJSONString(returnMap);
    }

    /**
     * AGV车体运行状态反馈
     * (AGV运行实时X坐标、AGV运行实时Y坐标、电量、状态等信息)
     * @param request HttpServletRequest
     * @return String
     */
    @PostMapping(value = "/carStatus")
    @ResponseBody
    public String carStatus(HttpServletRequest request) {
        String jsonStr = "";
        Map<String, Object> returnMap = Maps.newHashMap();
        try {
            jsonStr = RequestUtils.getPostData(request);
            logger.info("AGV车体运行状态反馈："+jsonStr);
        } catch (IOException e) {
            e.printStackTrace();
        }
        Map<String,Object> jsonMap = JSON.parseObject(jsonStr);
        returnMap.put("success", "True");
        returnMap.put("errCode", "");
        returnMap.put("errMsg", "");
        return JSONObject.toJSONString(returnMap);
    }

    /**
     * 自动扫码发送入库请求
     * @param request HttpServletRequest
     * @return String
     */
    @PostMapping(value = "/scanInComing")
    @ResponseBody
    public String scanInComing(HttpServletRequest request) {
        String jsonStr = "";
        Map<String, Object> returnMap = Maps.newHashMap();
        try {
            jsonStr = RequestUtils.getPostData(request);
            logger.info("自动扫码发送入库请求报文："+jsonStr);
        } catch (IOException e) {
            e.printStackTrace();
            returnMap.put("success", "False");
            returnMap.put("errCode", "002");
            returnMap.put("errMsg", "IOException");
            //记录接口日志：光电感应一维码触发入库请求
            interfaceLogService.insertLog("scanInComing","AMS-->>WMS 自动扫码发送入库请求",jsonStr,JSONObject.toJSONString(returnMap),
                    "","");
            return JSONObject.toJSONString(returnMap);
        }
        Map<String,Object> getJsonMap = JSON.parseObject(jsonStr);
        //条形码
        String barCode = (String) getJsonMap.get("code");
        logger.info("一维码信息："+barCode);
        //点位信息
        String locationFrom = (String) getJsonMap.get("locationFrom");
        logger.info("点位信息："+locationFrom);

        returnMap.put("success", "True");
        returnMap.put("errCode", "");
        returnMap.put("errMsg", "");

        //记录接口日志：光电感应一维码触发入库请求
        interfaceLogService.insertLog("scanInComing","AMS-->>WMS 自动扫码发送入库请求", jsonStr, JSONObject.toJSONString(returnMap),
                //一维码，点位信息
                barCode, locationFrom);

        //根据一维码信息及点位信息，获取对应的调拨任务单及明细信息，生成AGV任务发送给AMS
        return webApiClientService.storageInAddTask(barCode,locationFrom);
    }


    /**
     * 根据agv任务减去自有库存
     * @param agvTask
     */
    public void updateCutInventory(AgvTask agvTask){
        //叫料完成库存表需要减去相应的库存
        //根据点位获取仓库厂区仓库库位
        Shelf shelf = shelfService.selectOne(new EntityWrapper<Shelf>()
                .eq("AGV_POINT",agvTask.getLocationFrom()));
        //找到取货地
        YclInventoryEntity inventory = inventoryService.find(shelf.getFactoryCode(),shelf.getWarehouseCode(), shelf.getCode(), agvTask.getMaterialCode(),agvTask.getBatchNo());
        BigDecimal inventoryNewNum = inventory.getQuality().subtract(agvTask.getDeliveryNum());
        //最新的库存量 0的话删除该条数据 不为0则更新库存
        if (inventoryNewNum.compareTo(BigDecimal.ZERO) <= 0){
            inventoryService.delete(inventory.getId());
        }else{
            inventory.setQuality(inventoryNewNum);
            inventoryService.updateInventoryById(inventory);
        }
    }

    /**
     * 根据agv任务增加自有库存
     * @param agvTask
     */
    public void updateAddInventory(AgvTask agvTask){
        //根据点位获取仓库厂区仓库库位
        Shelf shelf2 = shelfService.selectOne(new EntityWrapper<Shelf>()
                .eq("AGV_POINT",agvTask.getLocationTo()));
        //库存里面插入一条数据
        YclInventoryEntity addInventory = new YclInventoryEntity();
        addInventory.setQuality(agvTask.getDeliveryNum());//数量
        addInventory.setUpdateTime(DateUtil.parseDateTime(DateUtil.now()));//更新时间
        addInventory.setStoreCode(shelf2.getWarehouseCode());//仓库
        addInventory.setLocatorCode(shelf2.getCode());//库位
        addInventory.setMaterialCode(agvTask.getMaterialCode());//物料
        addInventory.setAreaCode(shelf2.getFactoryCode());//厂区
        addInventory.setLotsNum(agvTask.getBatchNo());//批次
        inventoryService.save(addInventory);
    }

}
